package com.yxuan.springboot.controller;


import com.fasterxml.jackson.databind.ObjectMapper;
import com.tencentcloudapi.dayu.v20180709.models.SuccessCode;
import com.yxuan.springboot.mapper.OneParagraphMapper;
import com.yxuan.springboot.model.OneParagraph;
import com.yxuan.springboot.model.ProfessionalScore;
import com.yxuan.springboot.model.SchoolInformation;
import com.yxuan.springboot.service.OneParagraphService;
import com.yxuan.springboot.service.SchoolScoreService;
import com.yxuan.springboot.service.SearchForSchoolService;
import com.yxuan.springboot.util.Result;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.models.auth.In;
import lombok.extern.slf4j.Slf4j;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.client.core.CountRequest;
import org.elasticsearch.client.core.CountResponse;
import org.elasticsearch.client.indices.GetIndexRequest;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.RangeQueryBuilder;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.client.RestTemplate;


import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static com.yxuan.springboot.util.Code.SELECTALL_OK;
import static com.yxuan.springboot.util.Code.SUCCESSCODE;

@Slf4j
@Controller
@Api(tags = "根据分数，意向省份查询该分数对应排名，最终返回院校信息")
@RequestMapping(value = "/searchforschool", method = {RequestMethod.POST,RequestMethod.GET})
@CacheConfig(cacheNames = "searchforschool")//缓存名，和管理器中配置的一致
public class SearchForSchoolController {

    @Autowired
    private OneParagraphService oneParagraphService;

    @Autowired
    private SchoolScoreService schoolScoreService;

    @Autowired
    private SearchForSchoolService searchForSchoolService;

    @Autowired
    private OneParagraphMapper oneParagraphMapper;


    @ResponseBody
    @ApiOperation(value = "根据分数，意向省份查询该分数对应排名，最终返回院校信息", notes = "根据分数，意向省份查询该分数对应排名院校信息")
    @RequestMapping("/selectForInformationByScoreProvince")
    public List<Map<Object,Object>> selectForInfomation(@RequestBody OneParagraph oneParagraph) throws Exception {

        List<Map<Object, Object>> listMaps = searchForSchoolService.selectForInfomation(oneParagraph);

        return listMaps;
    }





    /**
     * 根据school_score表录取最低排名以及考生高考省份查询能上的所有学校个数,即where 排名>最低排名
     */
    @ApiOperation(value = "根据school_score表录取最低排名以及考生高考省份查询能上的所有学校个数", notes = "根据school_score表录取最低排名以及考生高考省份查询能上的所有学校个数")
    @RequestMapping("/searchForAvailableNumber")
    @ResponseBody
    public Result searchForAvailableNumber(@RequestBody OneParagraph oneParagraph) throws Exception {

        Map<String, Object> map = new HashMap<>();
        log.info(oneParagraph.toString());
        //根据分数，意向省份查询该分数对应的排名区间
        List<OneParagraph> manyByPramas = oneParagraphService.findManyByPramas(oneParagraph);
        OneParagraph targetOnePara = manyByPramas.get(0);
        //获得分数对应的位次区间
        log.info("=----------"+targetOnePara);
        if(targetOnePara==null){

            map.put("allavailableNumber",2828);
            return new Result(map,SUCCESSCODE,"查询所有合适学校数量成功");

        }


        log.info(targetOnePara.toString() + "##########");
        String targetIntervals = targetOnePara.getPeopelIntervals();
        //截取位次区间字符串里最低位次的内容
        String lowest_order = targetIntervals.substring(0, targetIntervals.indexOf("-"));
        //根据school_score表录取最低排名以及考生高考省份查询能上的所有学校数量,即where 排名>=最低排名
        Integer allAvailableNumber = schoolScoreService.findAllAvailableNumber(lowest_order, oneParagraph.getProvince());
        map.put("allavailableNumber",allAvailableNumber);
        return new Result(map,SELECTALL_OK,"查询所有合适学校数量成功");
    }



    //x
    @ApiOperation(value = "根据school_score表录取最低排名以及考生高考省份查询能上的所有学校个数", notes = "根据school_score表录取最低排名以及考生高考省份查询能上的所有学校个数")
    @RequestMapping("/searchForAvailableNumber1")
    @ResponseBody
    public Result searchForAvailableNumber1(@RequestBody OneParagraph oneParagraph) throws Exception {
        Map map = new HashMap();
        String rankOne = oneParagraphService.findRankOne(oneParagraph);
        map.put("allavailableNumber", rankOne);
        return new Result(map,SELECTALL_OK,"查询所有合适学校数量成功");
    }

    @ResponseBody
    @ApiOperation(value = "根据分数，意向省份查询该分数对应排名，最终返回院校信息", notes = "根据分数，意向省份查询该分数对应排名院校信息")
    @RequestMapping("/selectForInformationByScoreProvince1")
//    @Cacheable(key = "'schoolloadObjectByPramas-' + #oneParagraph",
//            unless = "#result==null",
//            condition = "#oneParagraph!=null")//#result返回结果
    public Result selectForInfomation1(@RequestBody OneParagraph oneParagraph) throws Exception {

        List<SchoolInformation> listMaps = searchForSchoolService.selectForInfomation1(oneParagraph);

        return new Result(listMaps, SUCCESSCODE);
    }


    @ResponseBody
    @ApiOperation(value = "根据分数，意向省份查询该分数对应排名，最终返回院校信息(ES)", notes = "根据分数，意向省份查询该分数对应排名院校信息")
    @RequestMapping("/selectForInformationByScoreProvince2")
//    @Cacheable(key = "'schoolloadObjectByPramas-' + #oneParagraph",
//            unless = "#result==null",
//            condition = "#oneParagraph!=null")//#result返回结果
    public Result selectForInfomation2(@RequestBody OneParagraph oneParagraph,Integer size) throws Exception {

        List<SchoolInformation> listMaps = searchForSchoolService.selectForInfomation2(oneParagraph,size);

        return new Result(listMaps, SUCCESSCODE);
    }

    @ResponseBody
    @ApiOperation(value = "根据院校id和专业名查专业信息")
    @RequestMapping("/selectProfeesionByIdAndProfessionName")
    // map中传入schoolId： 学校的id professionNmaeList：该院校的专业列表 year表示年份
    public Result selectProfeesionByIdAndProfessionName(@RequestBody SchoolInformation schoolInformation) throws Exception {
        Map<String, List<ProfessionalScore>> stringListMap = searchForSchoolService.selectProfeesionByIdAndProfessionName(schoolInformation);
        return new Result(stringListMap, SUCCESSCODE);
    }

    @ResponseBody
    @ApiOperation(value = "根据 学校id 和 考生分数 和 考生省份 查询数据")
    @RequestMapping("/selectInformationBySchoolIdAndUser")
    // map中传入schoolId： 学校的id professionNmaeList：该院校的专业列表 year表示年份
    public Result selectInformationBySchoolIdAndUser(@RequestBody Map map) throws Exception {
        return new Result(searchForSchoolService.selectInformationBySchoolIdAndUser(map), SUCCESSCODE);
    }

    @ResponseBody
    @ApiOperation(value = "根据 学校id 和 考生分数 和 考生省份 查询数据")
    @RequestMapping("/selectPrefeesionBySchoolId")
    // map中传入schoolId： 学校的id professionNmaeList：该院校的专业列表 year表示年份
    public Result selectPrefeesionBySchoolId(@RequestBody Map map) throws Exception {
        return new Result(searchForSchoolService.selectPrefeesionBySchoolId(map), SUCCESSCODE);
    }

    @Autowired
    private RestTemplate restTemplate;

    @Autowired
    private RestHighLevelClient restHighLevelClient;




    @ResponseBody
    @ApiOperation(value = "根据分数，意向省份  分页查询  该分数对应 数据总条数")
    @RequestMapping("/numberOfAllSchool")
    // map中传入schoolId： 学校的id professionNmaeList：该院校的专业列表 year表示年份
    public Result numberOfAllSchool(@RequestBody OneParagraph oneParagraph) throws Exception {
        String httpUrl = "pre_school_";
        httpUrl = httpUrl + oneParagraph.getYear() + oneParagraph.getProvince() + oneParagraph.getScore();

        String classifi =  oneParagraph.getClassification().substring(0,1);
        if(classifi.equals("物")){
            classifi = "物_化_生";
        }else{
            classifi = "历_地_政";
        }
        httpUrl = httpUrl + classifi;
        CountRequest countRequest = new CountRequest(httpUrl);
        CountResponse countResponse = restHighLevelClient.count(countRequest, RequestOptions.DEFAULT);
        Integer total = Math.toIntExact(countResponse.getCount());
        return new Result(total, SUCCESSCODE);
    }


    @ResponseBody
    @ApiOperation(value = "根据分数，意向省份  分页查询  该分数对应 数据总条数")
    @RequestMapping("/numberOftypeSchool")
    // map中传入schoolId： 学校的id professionNmaeList：该院校的专业列表 year表示年份
    public Result numberOftypeSchool(@RequestBody OneParagraph oneParagraph) throws Exception {
        String httpUrl = "pre_school_";
        httpUrl = httpUrl + oneParagraph.getYear() + oneParagraph.getProvince() + oneParagraph.getScore();

        String classifi =  oneParagraph.getClassification().substring(0,1);
        if(classifi.equals("物")){
            classifi = "物_化_生";
        }else{
            classifi = "历_地_政";
        }
        httpUrl = httpUrl + classifi;
        CountRequest countRequest = new CountRequest(httpUrl);
        CountResponse countResponse2 = restHighLevelClient.count(countRequest, RequestOptions.DEFAULT);
        Integer total = Math.toIntExact(countResponse2.getCount());


        Map<String,Object> map = new HashMap<>();


        // 查询985
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        BoolQueryBuilder jiubawu = boolQueryBuilder.must(QueryBuilders.termQuery("jiubawu", "0"));
        searchSourceBuilder.query(jiubawu);
        countRequest.source(searchSourceBuilder);
        CountResponse countResponse = restHighLevelClient.count(countRequest, RequestOptions.DEFAULT);
        Integer jiubawutotal = Math.toIntExact(countResponse.getCount());
        map.put("jiubawutotal",jiubawutotal);
        // 查询211
        SearchSourceBuilder searchSourceBuilder1 = new SearchSourceBuilder();
        BoolQueryBuilder boolQueryBuilder1 = QueryBuilders.boolQuery();
        BoolQueryBuilder eryaoyao = boolQueryBuilder1.must(QueryBuilders.termQuery("eryaoyao", "0"));
        searchSourceBuilder1.query(eryaoyao);
        countRequest.source(searchSourceBuilder1);
        countResponse = restHighLevelClient.count(countRequest, RequestOptions.DEFAULT);
        Integer eryaoyaototal = Math.toIntExact(countResponse.getCount());
        map.put("eryaoyaototal",eryaoyaototal);
        // 双一流
        SearchSourceBuilder searchSourceBuilder2 = new SearchSourceBuilder();
        BoolQueryBuilder boolQueryBuilder2 = QueryBuilders.boolQuery();
        BoolQueryBuilder doubleFirst = boolQueryBuilder2.must(QueryBuilders.termQuery("doubleFirst", "0"));
        searchSourceBuilder2.query(doubleFirst);
        countRequest.source(searchSourceBuilder2);
        countResponse = restHighLevelClient.count(countRequest, RequestOptions.DEFAULT);
        Integer doubleFirsttotal = Math.toIntExact(countResponse.getCount());
        map.put("doubleFirsttotal",doubleFirsttotal);
        // 公办
        SearchSourceBuilder searchSourceBuilder3 = new SearchSourceBuilder();
        BoolQueryBuilder boolQueryBuilder3 = QueryBuilders.boolQuery();
        BoolQueryBuilder nature = boolQueryBuilder3.must(QueryBuilders.termQuery("nature.keyword", "公办"));
        searchSourceBuilder3.query(nature);
        countRequest.source(searchSourceBuilder3);
        countResponse = restHighLevelClient.count(countRequest, RequestOptions.DEFAULT);
        Integer naturetotal = Math.toIntExact(countResponse.getCount());
        map.put("naturetotal",naturetotal);
        // 民办
        Integer nonaturetotal = total - naturetotal;
        map.put("nonaturetotal",nonaturetotal);
        // 省重点
        Integer pointtotal = eryaoyaototal;
        map.put("pointtotal",pointtotal);
        return new Result(map, SUCCESSCODE);
    }


    @ResponseBody
    @ApiOperation(value = "根据分数，意向省份  分页查询  该分数对应 数据")
    @RequestMapping("/getThreeTypeNumber")
    // map中传入schoolId： 学校的id professionNmaeList：该院校的专业列表 year表示年份
    public Result getThreeTypeNumber(@RequestBody OneParagraph oneParagraph) throws IOException {
        Map<String,Object> map = new HashMap<>();
        String httpUrl = "pre_school_";
        httpUrl = httpUrl + oneParagraph.getYear() + oneParagraph.getProvince() + oneParagraph.getScore();
//        httpUrl = httpUrl + oneParagraph.getClassification().replaceAll("/","_");
//        httpUrl = httpUrl + oneParagraph.getYear() + oneParagraph.getProvince() + oneParagraph.getScore();
//        httpUrl = httpUrl + oneParagraph.getClassification().replaceAll("/","_");
        String classifi =  oneParagraph.getClassification().substring(0,1);
        if(classifi.equals("物")){
            classifi = "物_化_生";
        }else{
            classifi = "历_地_政";
        }
        httpUrl = httpUrl + classifi;
        CountRequest countRequest = new CountRequest(httpUrl);


        // 可保底
        RangeQueryBuilder sprintableRange = QueryBuilders.rangeQuery("sprintable").gte(80);
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        boolQueryBuilder.must(sprintableRange);
        searchSourceBuilder.query(boolQueryBuilder);
        countRequest.source(searchSourceBuilder);
        CountResponse countResponse = restHighLevelClient.count(countRequest, RequestOptions.DEFAULT);
        map.put("baodi",countResponse.getCount());
        // 加稳妥
        RangeQueryBuilder sprintableRange2 = QueryBuilders.rangeQuery("sprintable").gte(50);
        RangeQueryBuilder sprintableRange3 = QueryBuilders.rangeQuery("sprintable").lt(80);
        BoolQueryBuilder boolQueryBuilder2 = QueryBuilders.boolQuery();
        SearchSourceBuilder searchSourceBuilder2 = new SearchSourceBuilder();
        boolQueryBuilder2.must(sprintableRange2);
        boolQueryBuilder2.must(sprintableRange3);
        searchSourceBuilder2.query(boolQueryBuilder2);
        countRequest.source(searchSourceBuilder2);
        CountResponse countResponse2 = restHighLevelClient.count(countRequest, RequestOptions.DEFAULT);
        map.put("wentuo",countResponse2.getCount());
        // 需冲刺
        RangeQueryBuilder sprintableRange4 = QueryBuilders.rangeQuery("sprintable").lt(50);
        BoolQueryBuilder boolQueryBuilder3 = QueryBuilders.boolQuery();
        SearchSourceBuilder searchSourceBuilder3 = new SearchSourceBuilder();
        boolQueryBuilder3.must(sprintableRange4);
        searchSourceBuilder3.query(boolQueryBuilder3);
        countRequest.source(searchSourceBuilder3);
        CountResponse countResponse3 = restHighLevelClient.count(countRequest, RequestOptions.DEFAULT);
        map.put("chongci",countResponse3.getCount());
        return new Result(map,SUCCESSCODE);

    };



    @ResponseBody
    @ApiOperation(value = "根据分数，意向省份  分页查询  该分数对应 数据")
    @RequestMapping("/pageByStuInfor")
    // map中传入schoolId： 学校的id professionNmaeList：该院校的专业列表 year表示年份
    public Result pageByStuInfor(@RequestBody OneParagraph oneParagraph,Integer page,Integer limit,String province,String gradation,Integer sort,Integer sprintable,Integer sprintableLte) throws Exception {


        Map<String,Object> map = new HashMap<>();


        String httpUrl = "pre_school_";
        httpUrl = httpUrl + oneParagraph.getYear() + oneParagraph.getProvince() + oneParagraph.getScore();
//        httpUrl = httpUrl + oneParagraph.getClassification().replaceAll("/","_");
        String classifi =  oneParagraph.getClassification().substring(0,1);
        if(classifi.equals("物")){
            classifi = "物_化_生";
        }else{
            classifi = "历_地_政";
        }
        httpUrl = httpUrl + classifi;
        CountRequest countRequest = new CountRequest(httpUrl);


        SearchRequest searchRequest = new SearchRequest(httpUrl);
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();


        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        // 省份查询
        if(province != null && !province.isEmpty()){
            BoolQueryBuilder provinceSe = boolQueryBuilder.must(QueryBuilders.termQuery("province.keyword", province));
            searchSourceBuilder.query(provinceSe);
            searchRequest.source(searchSourceBuilder);
        }


        //批次查询
        if(gradation != null && !gradation.isEmpty()) {
            BoolQueryBuilder gradationSe = boolQueryBuilder.must(QueryBuilders.termQuery("gradation.keyword", gradation));
            searchSourceBuilder.query(gradationSe);
            searchRequest.source(searchSourceBuilder);
        }

        // 按照 sprintable 字段排序 ，当sort为1时为升序，当sort为0时为降序
        if(sort != null) {
            SortOrder sortOrder = sort == 1 ? SortOrder.ASC : SortOrder.DESC;
            searchSourceBuilder.sort("sprintable", sortOrder);
            searchRequest.source(searchSourceBuilder);
        }

        // 搜索sprintable字段 大于 sprintable的数据
        if(sprintable != null) {
            RangeQueryBuilder sprintableRange = QueryBuilders.rangeQuery("sprintable").gte(sprintable);
            boolQueryBuilder.must(sprintableRange);
            searchSourceBuilder.query(boolQueryBuilder);
            searchRequest.source(searchSourceBuilder);
        }
        // 搜索sprintable字段 小于 sprintableLte的数据
        if(sprintableLte != null) {
            RangeQueryBuilder sprintableRange2 = QueryBuilders.rangeQuery("sprintable").lte(sprintableLte);
            boolQueryBuilder.must(sprintableRange2);
            searchSourceBuilder.query(boolQueryBuilder);
            searchRequest.source(searchSourceBuilder);
        }
        System.out.println(searchRequest);

        countRequest.source(searchSourceBuilder);
        CountResponse countResponse = restHighLevelClient.count(countRequest, RequestOptions.DEFAULT);
        Integer total = Math.toIntExact(countResponse.getCount());
        map.put("total",total);
        Integer from = (page-1) * limit;
        if(page * limit >= total){
            map.put("isFinish",true);
        }else{
            map.put("isFinish",false);
        }
        searchSourceBuilder.from(from);
        searchSourceBuilder.size(limit);
        searchRequest.source(searchSourceBuilder);
        ArrayList arrayList = new ArrayList();
        try {
            SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
            // 处理搜索响应结果
            SearchHit[] stringList = searchResponse.getHits().getHits();
            for (SearchHit hit:stringList){
                Map<String, Object> sourceAsString = hit.getSourceAsMap();
                arrayList.add(sourceAsString);
            }
            map.put("list",arrayList);
            System.out.println(searchResponse);
            return new Result(map,SUCCESSCODE);
//            try {
////                restHighLevelClient.close();
//                return new Result(arrayList,SUCCESSCODE);
//            } catch (IOException e) {
//                e.printStackTrace();
//                return null;
//            }
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }






    }


}
